/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mail.ui;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.EventListenerList;
import javax.swing.table.AbstractTableModel;
import mail.attribute.MailItem;
import mail.attribute.NullMailItem;
import mail.client.MailClient;
import mail.ui.event.MailItemEventListener;

/**
 *
 * @author Roberto
 * @author Timoteo Ponce - several changes
 */
public class MailListModel extends AbstractTableModel implements MailIterator {

    private final EventListenerList listenerList = new EventListenerList();
    private String columnNames[] = {"No.", "Subject", "Time", "Status"};
    private JTable table;
    private MailClient client;
    private int currentMailIndex;
    private List<MailItem> mails;

    public MailListModel(final JTable table, MailClient client) {
        this.table = table;
        this.client = client;
        table.setModel(this);
        refresh();
        updateSelectedIndex();
        table.addMouseListener(new MouseListener() {

            @Override
            public void mouseClicked(MouseEvent me) {
                int selectedRow = table.getSelectedRow();
                if (selectedRow > -1) {
                    currentMailIndex = selectedRow;
                    fireItemChanged();
                }
            }

            @Override
            public void mousePressed(MouseEvent me) {
            }

            @Override
            public void mouseReleased(MouseEvent me) {
            }

            @Override
            public void mouseEntered(MouseEvent me) {
            }

            @Override
            public void mouseExited(MouseEvent me) {
            }
        });

    }

    public void addListener(MailItemEventListener listener) {
        listenerList.add(MailItemEventListener.class, listener);
    }

    private void fireItemChanged() {
        MailItemEventListener[] listeners = listenerList.getListeners(MailItemEventListener.class);
        MailItem current = getCurrent();
        for (MailItemEventListener eventListener : listeners) {
            eventListener.itemChanged(current);
        }
    }

    @Override
    public int getRowCount() {
        return mails.isEmpty() ? 0 : mails.size();
    }

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        if (columnIndex == 0) {
            return (Object) String.valueOf(rowIndex + 1);
        }
        MailItem mail = mails.get(rowIndex);
        switch (columnIndex) {
            case 1:
                return mail.getSubject();
            case 2:
                return mail.getDate();
            case 3:
                return mail.isRead() ? "R" : "U";
        }
        return null;
    }

    @Override
    public MailItem getCurrent() {
        boolean noneSelected = mails.isEmpty() || getSelectedIndex() == -1;
        return noneSelected ? NullMailItem.NULL_ITEM : mails.get(currentMailIndex);
    }

    @Override
    public void goNext() {
        if (currentMailIndex < mails.size() - 1) {
            currentMailIndex++;
        }
        updateSelectedIndex();
    }

    @Override
    public void goPrevious() {
        if (currentMailIndex > 0) {
            currentMailIndex--;
        }
        updateSelectedIndex();
    }

    @Override
    public String getColumnName(int column) {
        return columnNames[column];
    }

    public void deleteAllMails() {
        client.deleteAllMails();
        mails = new ArrayList<MailItem>();
        currentMailIndex = -1;
    }

    public MailClient getMailClient() {
        return client;
    }

    public void refresh() {
        mails = client.getAllMails();
        if (mails.isEmpty()) {
            currentMailIndex = -1;
        }
        if (currentMailIndex > getRowCount()) {
            currentMailIndex = 0;
        }
    }

    private void updateSelectedIndex() {
        ListSelectionModel selectionModel = table.getSelectionModel();
        selectionModel.setSelectionInterval(currentMailIndex, currentMailIndex);
    }

    private int getSelectedIndex() {
        return table.getSelectedRow();
    }
}
